import styles from './ContentList.module.scss'
import { useLoaderData, useParams } from 'react-router-dom'
import SplitPane from 'react-split-pane'
import React, { useEffect, useState } from 'react'
import { Add, Delete, Redo } from '@icon-park/react'
import SyntaxHighlighter from 'react-syntax-highlighter'
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs'
import { ContextMenu, MenuItem, ContextMenuTrigger } from 'react-contextmenu'
import { Input } from 'antd'

const fetchContentList = async (cid: string, searchTerm = '') => {
  const query = searchTerm
    ? `select *
       from contents
       where title like @searchWord
         and category_id = ${cid}
       order by id desc`
    : `select *
       from contents
       where category_id = ${cid}
       order by id desc`

  const params = searchTerm ? { searchWord: '%' + searchTerm + '%' } : undefined
  return (await window.api.sql(query, 'findAll', params)) as any[]
}

export default function ContentListPage() {
  const list = useLoaderData()
  const { cid } = useParams()
  const [contentList, setContentList] = useState<any[]>(list || [])
  const [contentTmp, setContent] = useState<{
    id: number
    title: string
    content: string
    category_id: number
    created_at: string
  } | null>(null)
  const [contentId, setContentId] = useState<number>(-1)
  const [search, setSearch] = useState<string>('')

  useEffect(() => {
    setContentList(list)
    if (list.length > 0) {
      setContentId(list[0].id)
      setContent(list[0])
    } else {
      setContentId(-1)
      setContent(null)
    }
  }, [list])

  useEffect(() => {
    if (contentId !== -1) {
      const updateContent = contentList.find((item) => +item.id === +contentId)
      setContent(updateContent || null)
    }
  }, [contentId, contentList])

  const handleBlurTitle = async (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!contentTmp) return
    setContent({ ...contentTmp, title: e.target.value })
    try {
      await window.api.sql(
        `UPDATE contents
         SET title = '${e.target.value}'
         WHERE id = ${contentId}`,
        'update'
      )
      const updatedList = await fetchContentList(cid as string)
      setContentList(updatedList)
    } catch (error) {
      console.error('Error updating title:', error)
    }
  }
  const handleBlur = async (e: any, id) => {
    if (id === -1) return
    try {
      await window.api.sql(
        `UPDATE contents
         SET title = '${e.target.value}'
         WHERE id = ${id}`,
        'update'
      )
      const updatedList = await fetchContentList(cid as string)
      setContentList(updatedList)
    } catch (error) {
      console.error('Error updating title:', error)
    }
  }

  const handleBlurContent = async (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    if (!contentTmp) return
    setContent({ ...contentTmp, content: e.target.value })
    try {
      await window.api.sql(
        `UPDATE contents
         SET content = @content
         WHERE id = ${contentId}`,
        'update',
        { content: e.target.value }
      )
      const updatedList = await fetchContentList(cid as string)
      setContentList(updatedList)
      const updatedContent = updatedList.find((item) => +item.id === +contentId)
      setContent(updatedContent || null)
    } catch (error) {
      console.error('Error updating content:', error)
    }
  }

  const handleAdd = async () => {
    try {
      await window.api.sql(
        `INSERT INTO contents (title, content, category_id, created_at)
         VALUES ('未命名片段', '', ${cid}, datetime())`,
        'insert'
      )
      const updatedList = await fetchContentList(cid as string)
      setContentList(updatedList)
    } catch (error) {
      console.error('Error adding new content:', error)
    }
  }

  const handleDelete = async (id: number) => {
    try {
      await window.api.sql(
        `DELETE
         FROM contents
         WHERE id = ${id}`,
        'del'
      )
      const updatedList = await fetchContentList(cid as string)
      setContentList(updatedList)
      if (updatedList.length > 0) {
        setContentId(updatedList[0].id)
        setContent(updatedList[0])
      } else {
        setContentId(-1)
        setContent(null)
      }
    } catch (error) {
      console.error('Error deleting content:', error)
    }
  }

  const handleSearch = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const searchWord = e.target.value.trim()
    setSearch(searchWord)
    const updatedList = await fetchContentList(cid as string, searchWord)
    setContentList(updatedList)
  }
  const handleRename = (id: number) => {
    setContentList((prevCategories) =>
      prevCategories.map((item) => (item.id === id ? { ...item, isEdit: true } : item))
    )
  }

  return (
    <main className={styles.container}>
      {/* @ts-ignore*/}
      <SplitPane split="vertical" maxSize={300} defaultSize={200}>
        <div className={styles.left}>
          <div className={styles.list}>
            {contentList.map((item) => (
              <div key={item.id}>
                {item.isEdit ? (
                  <Input
                    onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) =>
                      e.key === 'Enter' && handleBlur(e, item.id)
                    }
                    onBlur={(e) => handleBlur(e, item.id)}
                    defaultValue={item.title}
                    style={{ height: '40px', boxShadow: 'none' }}
                  />
                ) : (
                  // @ts-ignore*
                  <ContextMenuTrigger id={`unique_item_${item.id}`}>
                    <div
                      onClick={() => setContentId(item.id)}
                      className={`${item.id === contentId ? styles.active : ''} ${styles.item} u-line-1`}
                    >
                      {item.title}
                    </div>
                  </ContextMenuTrigger>
                )}

                {/* @ts-ignore*/}
                <ContextMenu
                  id={`unique_item_${item.id}`}
                  hideOnLeave={true}
                  className={`py-[10px] box-border ${styles.contextMenu}`}
                >
                  {/* @ts-ignore*/}
                  <MenuItem
                    onClick={() => handleRename(item.id)}
                    className={styles.contextMenuItem}
                  >
                    <Redo theme="outline" size="16" fill="#333" style={{ marginRight: '9px' }} />
                    重命名
                  </MenuItem>
                  {/* @ts-ignore*/}
                  <MenuItem
                    onClick={() => handleDelete(item.id)}
                    className={styles.contextMenuItem}
                  >
                    <Delete theme="outline" size="16" fill="#333" style={{ marginRight: '9px' }} />
                    删除
                  </MenuItem>
                </ContextMenu>
              </div>
            ))}
          </div>
          {cid && (
            <div className={styles.nav}>
              <Add theme="outline" size="20" fill="#333" onClick={handleAdd} />
              <input className="border ml-2 flex-1 w-full" onChange={handleSearch} value={search} />
            </div>
          )}
        </div>
        {contentTmp ? (
          <div className="flex flex-col box-border w-full h-full">
            <input
              value={contentTmp.title}
              onChange={handleBlurTitle}
              className="text-xl font-bold h-[50px] text-center items-center outline-none"
            />
            <div className="flex-1 flex overflow-auto">
              <textarea
                className="flex-1 border-r"
                value={contentTmp.content}
                onChange={handleBlurContent}
              />
              <SyntaxHighlighter
                language="javascript"
                style={docco}
                className={`h-full flex-1 overflow-auto ${styles.highlightBox}`}
                codeTagProps={{ style: { whiteSpace: 'pre-wrap' } }}
              >
                {contentTmp.content}
              </SyntaxHighlighter>
            </div>
          </div>
        ) : (
          <div></div>
        )}
      </SplitPane>
    </main>
  )
}
